<?php

namespace hamster\mongodb;


trait BasicQuery
{
	/**
	 * 查询批量数据
	 * @return $this
	 * @example db.user.find({'name':{$in:['张三','李四']}}).skip(1).limit(1).sort({'age':1})
	 */
	public function find()
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【查询】
		$filter = self::$filter ?? [];
		$options = self::$options ?? [];
		$cursor = $bulk->find($filter, $options); // 成功的话，返回一个\MongoDB\Driver\Cursor实例。

		$this->_clear();

		$this->data = $cursor;
		return $this;
	}

	/**
	 * 查询单条数据
	 * @return $this
	 */
	public function findOne()
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【查询】
		$filter = self::$filter ?? [];
		$options = self::$options ?? [];
		$document = $bulk->findOne($filter, $options); // 成功的话，返回一个\MongoDB\Model\BSONDocument实例。

		$this->_clear();

		$this->data = $document;
		return $this;
	}

	/**
	 * 插入批量数据
	 * @param array $data 二维数组
	 * @return bool|int 成功返回插入数量
	 * @example db.user.insert({'name':'张三','age':'20'})
	 */
	public function insert($data)
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		if ($this->auto_increment) {
			foreach ($data as $key => $value) {
				$data[$key]['_id'] = $this->_autoIncrement();
			}
		}

		// 【插入】
		$insertOneResult = $bulk->insertMany($data); // 成功的话，返回一个\MongoDB\InsertOneResult实例。

		$this->_clear();

		if ($count = $insertOneResult->getInsertedCount()) { // 获取插入数量
			return $count;
		} else {
			return false;
		}
	}

	/**
	 * 插入单条数据
	 * @param array $data 一维数组
	 * @return bool|int|mixed|string 成功返回_id
	 */
	public function insertOne($data)
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		if ($this->auto_increment) {
			$data['_id'] = $this->_autoIncrement();
		}

		// 【插入】
		$insertOneResult = $bulk->insertOne($data); // 成功的话，返回一个\MongoDB\InsertOneResult实例。

		$this->_clear();

		if ($insertOneResult->getInsertedCount()) {
			$insertIdObject = $insertOneResult->getInsertedId(); // 获取插入数据的id
			if (is_object($insertIdObject)) {
				$insertIdData = json_decode(json_encode($insertIdObject), true);
				return $insertIdData['$oid'] ?? '';
			} elseif (is_numeric($insertIdObject)) {
				return $insertIdObject;
			} else {
				return '';
			}
		} else {
			return false;
		}
	}

	/**
	 * 修改批量数据
	 * @param array $data 一维数组
	 * @param bool $upsert 不存在数据时是否创建记录
	 * @return bool|int|null 成功返回修改数或者插入数
	 * @example db.user.update({'name':'张三'},{'$set':{'age':18}},upsert=true,multi=false)
	 */
	public function update($data, $upsert=false)
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【更新】
		$filter = self::$filter ?? [];
		$result = $bulk->updateMany( // 成功的话，返回一个MongoDB\UpdateResult实例。
			$filter,
			['$set' => $data],
			['upsert' => $upsert] // upsert不存在数据时是否创建记录
		);

		$this->_clear();

		if ($upsert) {
			$count = $result->getUpsertedCount(); // getUpsertedId()获取插入id
		} else {
			$count = $result->getModifiedCount();
		}
		if ($count > 0) {
			return $count;
		} else {
			return false;
		}
	}

	/**
	 * 修改单条数据
	 * @param array $data 一维数组
	 * @param bool $upsert 不存在数据时是否创建记录
	 * @return bool|int|null 成功返回修改数或者插入数
	 */
	public function updateOne($data, $upsert=false)
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【更新】
		$filter = self::$filter ?? [];
		$result = $bulk->updateOne( // 成功的话，返回一个MongoDB\UpdateResult实例。
			$filter,
			['$set' => $data],
			['upsert' => $upsert] // upsert不存在数据时是否创建记录
		);

		$this->_clear();

		if ($upsert) {
			$count = $result->getUpsertedCount(); // getUpsertedId()获取插入id
		} else {
			$count = $result->getModifiedCount();
		}
		if ($count > 0) {
			return $count;
		} else {
			return false;
		}
	}

	/**
	 * 删除批量数据
	 * @return bool|int 成功返回删除数
	 */
	public function delete()
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【删除】
		$filter = self::$filter ?? [];
		$result = $bulk->deleteMany($filter); // 成功的话，返回一个MongoDB\DeleteResult实例。

		$this->_clear();

		if ($count = $result->getDeletedCount()) {
			return $count;
		} else {
			return false;
		}
	}

	/**
	 * 删除单条数据
	 * @return bool|int 成功返回删除数
	 */
	public function deleteOne()
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【删除】
		$filter = self::$filter ?? [];
		$result = $bulk->deleteOne($filter); // 成功的话，返回一个MongoDB\DeleteResult实例。

		$this->_clear();

		if ($count = $result->getDeletedCount()) {
			return $count;
		} else {
			return false;
		}
	}

	/**
	 * 统计数量
	 * @return int
	 * @example db.user.find({'age':20}).count()
	 */
	public function count()
	{
		$collection = $this->collection;
		$bulk = self::$db->$collection;
		if ($bulk instanceof \MongoDB\Collection)

		// 【统计】
		$filter = self::$filter ?? [];
		$options = self::$options ?? [];
		$num = $bulk->countDocuments($filter, $options);

		$this->_clear();

		return $num;
	}

	/**
	 * 转换数组格式
	 * @return array|mixed|null
	 */
	public function toArray()
	{
		if (!empty($this->data)) {
			if ($this->data instanceof \MongoDB\Model\BSONDocument) {
				$data = json_decode(json_encode($this->data), true);
				$data['id'] = $data['_id']['$oid'];
			} elseif ($this->data instanceof \MongoDB\Driver\Cursor) {
				$data = [];
				foreach ($this->data as $document) {
					$document = json_decode(json_encode($document), true);
					if (isset($document['_id']['$oid'])) $document['id'] = $document['_id']['$oid'];
					$data[] = $document;
				}
			} else {
				$data = null;
			}
		}
		return $data;
	}


	/**
	 * 自增id
	 * @return bool|int|mixed
	 */
	protected function _autoIncrement()
	{
		$collection = $this->collection;

		$bulk = self::$db->increasing_id;
		if ($bulk instanceof \MongoDB\Collection)

			// 用一张新表记录id的递增数
			$result = $bulk->findOneAndUpdate(
				['collection' => $collection],
				['$inc' => ['id'=>1]],
				['upsert' => true]
			);

		if ($result instanceof \MongoDB\Model\BSONDocument) {
			$data = json_decode(json_encode($result), true);
			$id = $data['id'] + 1; // 先查后增加，数量会比实际少1
		} elseif (is_null($result)) {
			$id = 1;
		} else {
			$id = false;
		}

		return $id;
	}

	// 清空过滤条件和命令选项
	protected function _clear()
	{
		self::$filter = null;
		self::$options = null;
	}
}